#include "Behaviour.h"
#include "GameObject.h"
#include "Scene.h"
#include "Logger.h"

using namespace game_engine;
using namespace game_engine::components;
using namespace game_engine::utils;

///////////////////////////////////////////////////////////////////////////////
// Constructors and Destructors
///////////////////////////////////////////////////////////////////////////////

Behaviour::Behaviour(void)
    : Component(), currentState(NULL)
{
    type = "Behaviour";
}

Behaviour::Behaviour(GameObject *obj)
    : Component(obj), currentState(NULL)
{
    type = "Behaviour";
}

Behaviour::~Behaviour(void)
{
}

///////////////////////////////////////////////////////////////////////////////
// Other public methods
///////////////////////////////////////////////////////////////////////////////

void Behaviour::initialize(void) throw(...)
{
    if (currentState != NULL)
    {
        currentState->onEnter();
    }
}

void Behaviour::update(const FLOAT32 time)
{
    if (currentState != NULL)
    {
        State *newState = currentState->getNextState();
        if ((newState != NULL) && (newState != currentState))
        {
            // Execute transition
            currentState->onExit();
            currentState = newState;
            currentState->onEnter();
        }

        currentState->onLoop(time);
    }
    else
    {
        Logger::WARN(GAMEENGINE_LOG, string("no current state defined for object ")
            + object->getName());
    }
}

void Behaviour::finalize(void)
{
    if (currentState != NULL)
    {
        currentState->onExit();
    }
}

///////////////////////////////////////////////////////////////////////////////
// Getters
///////////////////////////////////////////////////////////////////////////////

State* Behaviour::getCurrentState(void) const
{
    return currentState;
}

///////////////////////////////////////////////////////////////////////////////
// Setters
///////////////////////////////////////////////////////////////////////////////

void Behaviour::setCurrentState(State *st)
{
    currentState = st;
}
